import { CarouselType } from "@/data/home/homeTypes";
import { isVideo } from "@/utils/isVideo";
import { ITouchEvent, View } from "@tarojs/components";
import { AbstractButton, AbstractImage, AbstractVideo, C45JumpMiniProgram } from "@/components";
import { useEffect, useState } from "react";
import { navigateTo, switchTab } from "@/utils/navigation";
import { gsap } from "gsap";
import { usePageDimensions } from "@/hooks/usePageDimensions";
import { useDidHide, useDidShow } from "@tarojs/taro";
import { PagesNavigation } from "@/data/pages/pagesTypes";
import { sendAction, ActionNames, ActionKeys } from "@/utils/tracking";
import style from "./index.module.scss";
import { useApplicationInfo } from "@/store/applicationDataContext";
// 新增的跳转小程序
import { navigateToMiniProgram } from "@/utils/navigation";


interface CarouselProps {
  carouselItems: CarouselType[];
}

const safeArrayIndex = (number: number, arr: Array<any>) => {
  if (number > arr.length - 1) {
    return 0;
  } else if (number < 0) {
    return arr.length - 1;
  } else {
    return number;
  }
};

const CHANGE_SLIDE_TIMER = 10000;

const C01Carousel = ({ carouselItems }: CarouselProps) => {
  const { dispatch } = useApplicationInfo();
  const [activeIdx, setActiveIdx] = useState(0);
  // Initialized to high number for first animation
  const [prevActiveIdx, setPrevActiveIdx] = useState(999);
  const [prevIdx, setPrevIdx] = useState(0);
  const [nextIdx, setNextIdx] = useState(0);
  const [touchStartX, setTouchStartX] = useState<number | null>(null);
  const [xOffset, setXOffset] = useState(0);
  const [xOffsetTarget, setXOffsetTarget] = useState<number | null>(null);
  const [initialRender, setInitialRender] = useState(true);
  const [renderData, setRenderData] = useState<CarouselType[]>([]);
  const [intervalTrigger, setIntervalTrigger] = useState<boolean>(true);

  const allowScroll = carouselItems.length > 1;

  const { heightExclNavbar, screenWidth } = usePageDimensions();

  // Circulate slider timer
  // Note: watching touchStartX -> not worth resetting on each touchmove
  useEffect(() => {
    if (allowScroll && intervalTrigger) {
      const interval = setInterval(() => {
        setXOffsetTarget(-screenWidth);
      }, CHANGE_SLIDE_TIMER);

      return () => clearInterval(interval);
    }
  }, [touchStartX, intervalTrigger]);

  // Special treatment to make sure carosel updates stop on hide and restarts on show
  useDidHide(() => {
    setIntervalTrigger(false);
  });
  useDidShow(() => {
    setIntervalTrigger(true);
  });

  // Initial transition
  useEffect(() => {
    setTimeout(() => {
      setInitialRender(false);
    }, 800);
  }, []);

  // Setting prev/next indices
  useEffect(() => {
    setPrevIdx(safeArrayIndex(activeIdx - 1, renderData));
    setNextIdx(safeArrayIndex(activeIdx + 1, renderData));
  }, [activeIdx, renderData]);

  // Handle easing of touch events
  useEffect(
    () => {
      if (xOffsetTarget !== null) {
        const offset = { value: xOffset };

        gsap.to(offset, {
          value: xOffsetTarget,
          duration: Math.abs(xOffsetTarget - xOffset) * 0.002,
          onUpdate: () => {
            setXOffset(offset.value);
          },
          onComplete: () => {
            setXOffsetTarget(null);
            setTouchStartX(null);
            if (Math.abs(offset.value) === screenWidth) {
              const nextIndexDir = -Math.sign(offset.value);
              setPrevActiveIdx(activeIdx);
              setActiveIdx(
                safeArrayIndex(activeIdx + nextIndexDir, carouselItems)
              );
              setXOffset(0);
            }
          },
        });
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [xOffsetTarget]
  );

  const calcBaseBackgroundOffset = (index: number) => {
    switch (index) {
      case activeIdx:
        return 0;
        break;
      case prevIdx:
        return -screenWidth;
        break;
      case nextIdx:
        return screenWidth;
        break;

      default:
        // Hide if longer list
        return 2 * screenWidth;
        break;
    }
  };

  // Repack input props (2 slides need to duplicate to slide right/left)
  const isTwoItems = carouselItems.length === 2;
  useEffect(() => {
    if (isTwoItems) {
      setRenderData([...carouselItems, ...carouselItems]);
    } else {
      setRenderData(carouselItems);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [carouselItems]);

  const transitionElementsActiveCheck = (
    idx: number,
    touchStartCheck: boolean = false
  ) => {
    const touchStart = touchStartCheck ? touchStartX === null : true;
    return idx === activeIdx && !initialRender && touchStart
      ? style.active
      : "";
  };

  // External function to force end of touch if touchEnd not called
  const slideBackOrNext = () => {
    if (Math.abs(xOffset) > 0.1 * screenWidth) {
      setXOffsetTarget(Math.sign(xOffset) * screenWidth);
    } else {
      setXOffsetTarget(0);
    }
  };



  return (
    <View>
      <View
        className={style["carousel-wrapper"]}
        onClick={() => {
          sendAction(ActionNames.HomePicExploreClick, {
            [ActionKeys.HomeContentName]: renderData[activeIdx].title.reduce((pre, next) => pre + next, ""),
          });

          if (renderData[activeIdx].hasOwnProperty("appid") && renderData[activeIdx]['appid']) {
            const { appid, buttonLink } = renderData[activeIdx];
            {/* 新增的跳转小程序 */ }
            navigateToMiniProgram(appid, buttonLink);

          } else if (renderData[activeIdx].buttonLink.includes("pages/discover/index")) {
            const id = renderData[activeIdx].buttonLink.split("=")[1];
            dispatch({
              type: "DISCOVER_TAB",
              data: {
                tab: +id,
              },
            });
            switchTab("pages/discover/index");
          } else {
            navigateTo(renderData[activeIdx].buttonLink as PagesNavigation);
          }

        }}
      >
        <View
          className={style["background-wrapper"]}
          style={{ height: heightExclNavbar }}
          onTouchStart={(e: ITouchEvent) => {
            if (allowScroll && xOffsetTarget === null) {
              setTouchStartX(e.touches[0].clientX);
            }
          }}
          onTouchMove={(e: ITouchEvent) => {
            if (touchStartX !== null && xOffsetTarget === null) {
              // If too staggering - could move to make use of setXOffsetTarget()
              setXOffset(e.touches[0].clientX - touchStartX);
            }
          }}
          onTouchEnd={(_) => {
            if (touchStartX !== null && xOffsetTarget === null) {
              slideBackOrNext();
            }
          }}
        >
          {renderData.map((carouselData, backgroundIndex) => (
            <View key={backgroundIndex}>
              {carouselData.video ? (
                // && isVideo(carouselData.video)
                <AbstractVideo
                  className={style.cover}
                  src={carouselData.video}
                  style={{
                    height: heightExclNavbar,
                    transform: `translate(${calcBaseBackgroundOffset(backgroundIndex) + xOffset
                      }px, 0)`,
                  }}
                />
              ) : (
                <AbstractImage
                  className={style.cover}
                  src={carouselData.backImage}
                  type="none"
                  style={{
                    height: heightExclNavbar,
                    transform: `translate(${calcBaseBackgroundOffset(backgroundIndex) + xOffset
                      }px, 0)`,
                  }}
                />
              )}
            </View>
          ))}
        </View>

        {/* Progress */}
        {allowScroll && (
          <View className={style["progress-wrapper"]}>
            {carouselItems.map((_, idx) => (
              <View
                className={`${style["progress-wrapper-item"]} ${idx === activeIdx ? style.active : ""
                  }`}
                key={idx}
              />
            ))}
          </View>
        )}

        {/* Title and Subtitle and CTA-buttons */}
        {carouselItems.map((carouselData, idx) => (
          <View
            key={carouselData.id}
            className={style["content-wrapper"]}
            style={{
              transform: `translate(${calcBaseBackgroundOffset(idx) + xOffset
                }px, 0)`,
              opacity: idx === activeIdx && touchStartX === null ? 1 : 0,
            }}
          >
            {carouselData.isTitleDisplayed && (
              <View className={style["text-wrapper"]}>
                <View className={style["text-title"]}>
                  {carouselData.title.map((titleChunk, titleChunkIdx) => {
                    const sx: { color?: string; fontSize?: string } = {};
                    if (carouselData.titleColor) {
                      sx.color = carouselData.titleColor;
                    }
                    if (carouselData.titleFontSize) {
                      sx.fontSize =
                        parseInt(carouselData.titleFontSize) * 2 + "rpx";
                    }
                    return (
                      <View
                        className={`${style["text-title-chunk"]}
                  ${transitionElementsActiveCheck(idx)}`}
                        key={titleChunkIdx}
                        style={sx}
                      >
                        {titleChunk}
                      </View>
                    );
                  })}
                </View>
                <View
                  className={`${style["text-subtitle"]}
                ${transitionElementsActiveCheck(idx, true)}`}
                >
                  {carouselData.text.split(/\n/).map((subChunk, subChunkIdx) => {
                    const sx: { color?: string; fontSize?: string } = {};
                    if (carouselData.textColor) {
                      sx.color = carouselData.textColor;
                    }
                    return (
                      <View key={subChunkIdx} style={sx}>
                        {subChunk}
                      </View>
                    );
                  })}
                </View>
              </View>
            )}

            {carouselData.isButtonDisplayed && (
              <View
                className={`
            ${style["cta-button"]}
            ${transitionElementsActiveCheck(idx, true)}
              `}
              >
                <AbstractButton
                  color="carousel-semi-transparent"
                >
                  {carouselData.buttonText}
                </AbstractButton>
              </View>
            )}
          </View>
        ))}

        {/* Scroll down possible-indication */}
        <View className={style["scroll-down-wrapper"]}>
          <View className={style["scroll-down-text"]}>向下滑动查看更多</View>
          <View className={style["scroll-down-indicator"]}>
            <View className={style["scroll-down-indicator--active"]} />
          </View>
        </View>
      </View>


    </View>
  );
};

export default C01Carousel;
